import uuid, logging

from django.conf import settings
from django.http import HttpResponse, Http404
import re, random
from django.views.decorators.http import require_http_methods

from utils import redis_client_db1, query_utils
from chat.models import FansMessage, AtMessage
from forum.models import Topic, Comment
from user_app.models import AccountInfo, AccountFollow, Role, ActivityRegisterInfo
from utils.common_utils import json_response, Pagination
from utils.decorators import json_check, check_login, get_token_info
from utils.encrypt_util import md5
from utils.time_util import now
from utils.yunpian_sms import YunpianSms

logger = logging.getLogger(__name__)
error_logger = logging.getLogger("error")


@json_check
def send_valid_code(request, json_data):
    phone = json_data.get("phone")
    module = json_data.get("module")
    if module == "forget_password":
        # 忘记密码模块，发送验证码前需要检验是否注册
        if not AccountInfo.objects.filter(mobile_phone=phone).exists():
            return json_response({"code": 1000, "message": "手机号未注册，请先注册"})
    else:
        # 注册模块需要判断手机号是否被注册
        if AccountInfo.objects.filter(mobile_phone=phone).exists():
            return json_response({"code": 1000, "message": "手机号已注册"})
    code = str(random.randint(100000, 999999))
    key = "verifycode_" + phone
    redis_client_db1.set(key, code, ex=60*30)
    context = {
        "code": code,
    }
    sms = YunpianSms()
    sms.send_register_sms(phone, context)
    return json_response({"code": 0, "message": "验证码发送成功"})


@json_check
def register_account(request, json_data):
    nick_name = json_data.get("nickname").strip()
    phone = json_data.get("phone").strip()
    password = json_data.get("password").strip()
    verifycode = json_data.get("verifycode")
    phone_regex = re.match(r"^(1[1-9][0-9])\d{8}$", phone)
    if not phone_regex:
        return json_response({"code": 1000, "message": "你输入的手机号格式不正确"})
    if not nick_name.strip():
        return json_response({"code": 1000, "message": "昵称不能为空"})
    if AccountInfo.objects.filter(mobile_phone=phone):
        return json_response({"code": 1000, "message": "手机号已被注册"})
    if AccountInfo.objects.filter(nick_name=nick_name):
        return json_response({"code": 1000, "message": "昵称已被占用"})
    key = "verifycode_" + phone
    code = redis_client_db1.get(key)
    if not code:
        return json_response({"code": 1000, "message": "验证码已失效，请重新获取"})
    elif verifycode != code:
        return json_response({"code": 1000, "message": "验证码错误"})
    redis_client_db1.delete(key)
    new_account = AccountInfo()
    new_account.nick_name = nick_name
    new_account.mobile_phone = phone
    new_account.password = md5(settings.PASSWORD_SALT + password)
    new_account.avatar = r'https://91mogo.oss-cn-beijing.aliyuncs.com/bbs/default1.png'
    new_account.save()
    return json_response({"code": 0, "message": "注册成功"})


@json_check
def login(request, json_data):
    phone = json_data.get("phone")
    password = json_data.get("password")
    account = AccountInfo.objects.filter(mobile_phone=phone)
    if not account:
        return json_response({"code": 1000, "message": "手机号未注册"})
    form_pwd = md5(settings.PASSWORD_SALT + password)
    db_pwd = account[0].password
    if form_pwd != db_pwd:
        return json_response({"code": 1000, "message": "密码错误"})
    account.update(last_login=now())
    # 补充session部分
    request.session['phone'] = phone
    request.session['password'] = form_pwd
    request.session['account_id'] = account[0].id
    x_api_token = uuid.uuid4().hex
    user_info = {
        'phone': phone,
        'password': form_pwd,
        'account_id': account[0].id,
    }
    # 过期时间2周
    redis_client_db1.hmset(x_api_token, user_info)
    redis_client_db1.expire(x_api_token, 1209600)
    return json_response({"code": 0, "message": "登录成功", "data": {"token": x_api_token}})


@check_login
def logout(request):
    session_key = request.session.session_key
    if session_key:
        request.session.delete(session_key)
    if request.META.get('HTTP_X_API_TOKEN'):
        x_api_token = request.META.get('HTTP_X_API_TOKEN')
        redis_client_db1.delete(x_api_token)
    return json_response({"code": 0, "message": "注销成功"})


@json_check
def forget_password(request, json_data):
    phone = json_data.get("phone")
    password = json_data.get("password")
    verifycode = json_data.get("verifycode")
    acc_info = AccountInfo.objects.filter(mobile_phone=phone)
    if not acc_info:
        return json_response({"code": 1000, "message": "手机号未注册"})
    key = "verifycode_" + phone
    code = redis_client_db1.get(key)
    if not code:
        return json_response({"code": 1000, "message": "验证码已失效，请重新获取"})
    elif verifycode != code:
        return json_response({"code": 1000, "message": "验证码错误"})
    redis_client_db1.delete(key)
    acc_info.update(password=md5(settings.PASSWORD_SALT + password))
    return json_response({"code": 0, "message": "密码重置成功"})


@check_login
def get_account_info(request):
    try:
        # 返回用户基本信息
        account_id = request.session['account_id']
        phone = request.session['phone']
        password = request.session['password']
        #print(request.session.session_key)
        account = AccountInfo.objects.filter(mobile_phone=phone, password=password)
        if not account:
            return json_response({"code": 2000, "message": "密码已修改，请重新登录"})
        fm_count = FansMessage.objects.filter(receive_id=account_id, is_read=False).count()
        am_count = AtMessage.objects.filter(receive_id=account_id, is_read=False).count()
        role_info = Role.objects.get(id=account[0].role_id)
        data = {
            "id": account[0].id,
            "nickname": account[0].nick_name,
            "mobile_phone": account[0].mobile_phone,
            "avatar": account[0].avatar,
            "message_count": fm_count + am_count,
            "is_superuser": account[0].is_superuser,
            "role_name": role_info.role_name,
            "module_list": role_info.module_list,
            "module_list_name": query_utils.module_list_to_name(role_info.module_list),
        }
        return json_response({"code": 0, "message": "用户信息获取成功", "data": data})
    except Exception as e:
        error_logger.exception("get_account_info have a  error ---->%s" % e.__str__())
        return json_response({"code": 2000, "message": "登录信息已过期，请重新登录"})


@check_login
def add_follow(request):
    follow_account_id = request.GET.get("follow_account_id")
    account_id = request.session['account_id']
    if follow_account_id:
        if follow_account_id == str(account_id):
            return json_response({"code": 1000, "message": "不能关注自己"})
        result_dict = {}
        follow_info = AccountFollow.objects.filter(follow_account_id=follow_account_id, created_by_id=account_id)
        if follow_info:
            follow_info.delete()
            result_dict['flag'] = False
            FansMessage.objects.filter(receive_id=follow_account_id, created_by_id=account_id, is_read=False).delete()
            return json_response({"code": 0, "message": "取消关注成功", "data": result_dict})
        else:
            account_follow = AccountFollow()
            account_follow.follow_account_id = follow_account_id
            account_follow.created_by_id = account_id
            account_follow.save()
            fm = FansMessage()
            fm.receive_id = follow_account_id
            fm.created_by_id = account_id
            fm.save()
            result_dict['flag'] = True
            return json_response({"code": 0, "message": "关注成功", "data": result_dict})
    else:
        return json_response({"code": 3000, "message": "请求参数错误"})


@require_http_methods(['POST'])
@get_token_info
@json_check
def activity_reg_account(request, json_data):
    """
        活动登记报名接口
    """
    nick_name = json_data.get("nickname").strip()
    phone = json_data.get("phone").strip()
    company = json_data.get("company").strip()
    location = json_data.get("location").strip().replace(" ", "")
    province_code = json_data.get("province_code").strip()
    city_code = json_data.get("city_code").strip()
    password = "666666"
    phone_regex = re.match(r"^(1[1-9][0-9])\d{8}$", phone)
    if not phone_regex:
        return json_response({"code": 1000, "message": "你输入的手机号格式不正确"})
    if not nick_name.strip():
        return json_response({"code": 1000, "message": "昵称不能为空"})
    session_phone = request.session.get("phone")
    if session_phone and session_phone != phone:
        return json_response({"code": 1000, "message": "你输入的手机号与当前登录帐号不匹配，请重新输入"})
    # 返回值标识，2为活动中新注册的用户，1为bbs用户报名
    tag = 1
    # 注册过BBS的用户
    if AccountInfo.objects.filter(mobile_phone=phone).exists():
        tag = 1
        account = AccountInfo.objects.get(mobile_phone=phone)
        account_id = account.id
        if ActivityRegisterInfo.objects.filter(account_id=account_id).exists():
            # 报过名的用户
            return json_response({"code": 0, "message": "已报名", "tag": tag})
        else:
            # 未报名的用户
            # account.company = company
            # account.location = location
            # account.province_code = province_code
            # account.city_code = city_code
            # account.save()
            ag = ActivityRegisterInfo()
            ag.account_id = account_id
            ag.mobile_phone = phone
            ag.nick_name = nick_name
            ag.province_code = province_code
            ag.city_code = city_code
            ag.company = company
            ag.location = location
            ag.save()
            return json_response({"code": 0, "message": "报名成功", "tag": tag})
    else:
        # 未注册到平台的用户
        new_account = AccountInfo()
        new_account.nick_name = nick_name
        new_account.mobile_phone = phone
        new_account.password = md5(settings.PASSWORD_SALT + password)
        new_account.avatar = r'https://91mogo.oss-cn-beijing.aliyuncs.com/bbs/default1.png'
        new_account.company = company
        new_account.location = location
        new_account.province_code = province_code
        new_account.city_code = city_code
        new_account.save()
        new_account.refresh_from_db()
        # 完全新用户登记活动
        ag = ActivityRegisterInfo()
        ag.account_id = new_account.id
        ag.mobile_phone = phone
        ag.nick_name = nick_name
        ag.province_code = province_code
        ag.city_code = city_code
        ag.company = company
        ag.location = location
        ag.save()

        # x_api_token = uuid.uuid4().hex
        # user_info = {
        #     'phone': phone,
        #     'password': password,
        #     'account_id': account_id,
        # }
        # # 过期时间2周
        # redis_client_db1.hmset(x_api_token, user_info)
        # redis_client_db1.expire(x_api_token, 1209600)
        tag = 2
        return json_response({"code": 0, "message": "报名成功", "tag": tag})


@require_http_methods(['GET'])
@check_login
def activity_check_reg(request):
    # 检查是否有报名活动
    account_id = request.session['account_id']
    if ActivityRegisterInfo.objects.filter(account_id=account_id).exists():
        return json_response({"code": 0, "message": "已报名"})
    else:
        return json_response({"code": 0, "message": "未报名"})
